﻿// 888 Listen to a channel 
// 555 Listen to open channel

//Asterisk CLI
 //core show applications

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.Windows.Threading;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using AsterNET.Manager;
using AsterNET.Manager.Action;
using AsterNET.Manager.Response;
using AsterNET.FastAGI;
using AsterNET.Manager.Event;
using AsterNET.FastAGI.MappingStrategies;
using System.Data.SqlClient;
using System.Data;
using MySql.Data;
using MySql.Data.MySqlClient;
//using System.Windows.Forms;

namespace WpfAsteriskCTI
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        //*********************************** Public Proprties **************************************************************
        #region Public Properties      

        System.Windows.Forms.NotifyIcon astIcon = new System.Windows.Forms.NotifyIcon();
        public AsterNET.Manager.ManagerConnection astCon;

        ObservableCollection<DataClasses.NewCall> lstNewCalls = new ObservableCollection<DataClasses.NewCall>();
        ObservableCollection<DataClasses.NewState> lstNewState = new ObservableCollection<DataClasses.NewState>();
        ObservableCollection<DataClasses.RingGroups> lstRingGroups = new ObservableCollection<DataClasses.RingGroups>();
        ObservableCollection<DataClasses.LocalExtension> lstLocalExtensions = new ObservableCollection<DataClasses.LocalExtension>();
        ObservableCollection<DataClasses.Trunks> lstTrunks = new ObservableCollection<DataClasses.Trunks>();
        ObservableCollection<DataClasses.Hangup> lstHangup = new ObservableCollection<DataClasses.Hangup>();
        ObservableCollection<DataClasses.History> lstHistory = new ObservableCollection<DataClasses.History>();
        ObservableCollection<DataClasses.ParkedCalls> lstParkedCalls = new ObservableCollection<DataClasses.ParkedCalls>();
        ObservableCollection<DataClasses.NewChannel> lstNewChannel = new ObservableCollection<DataClasses.NewChannel>();
        ObservableCollection<DataClasses.Hold> lstHold = new ObservableCollection<DataClasses.Hold>();
        ObservableCollection<DataClasses.Presence> lstPresencestate = new ObservableCollection<DataClasses.Presence>();
        ObservableCollection<DataClasses.UserPresence> lstUserPresencestate = new ObservableCollection<DataClasses.UserPresence>();
        ObservableCollection<DataClasses.CustomPhonebook> lstCustomPhonebook = new ObservableCollection<DataClasses.CustomPhonebook>();

        System.Windows.Threading.DispatcherTimer myCountdownTimer = new System.Windows.Threading.DispatcherTimer();
        System.Windows.Threading.DispatcherTimer myNotifyTimer = new System.Windows.Threading.DispatcherTimer();
        System.Windows.Threading.DispatcherTimer myExtensionStateTimer = new System.Windows.Threading.DispatcherTimer();

        //string mysqlconnection = "Server=192.168.0.66;Database=asteriskcdrdb;Uid=martin;Pwd=1q2w3e4r5t;";
        string mysqlconnection;
        private string astHost = "192.168.0.66";
        private int astPort = 5038;
        private string astUser = "mas";
        private String astPass = "1q2w3e4r5t";
        private String astExtension = "10";
        private String astCallerId = "";
        
        private string astPeerType = "SIP";

        private string activeChannelUp = null;
        private string activeChannelSelected = null;
        private string activeChannelParty = null;

        private string activeUniqueId = null;

        private string MOHExtension = null;
        private string MOHQueue = null;

        private string newNumber;
        private string oldNumber;

        private string numberToDial;


        bool logging = true;
        #endregion
        //*********************************** Main Window **************************************************************
        # region Main Window
        public MainWindow()
        {
            InitializeComponent();

            MouseLeftButtonDown+= delegate { DragMove(); };

            try
            {
               LoadProperties();
            }
            catch (Exception ex)
            {
                myLogger.LogError(string.Format("Error loading to {0}. Error: {1}", "Properties", ex.Message), logging);
            }
            try
            {
                string sPath = System.AppDomain.CurrentDomain.BaseDirectory;
                sPath = sPath + "Configuration\\config.ini";
                cIniReader _ini = new cIniReader(sPath);
                MOHExtension = _ini.ReadString("Asterisk", "MOHExtension", "");
                MOHQueue = _ini.ReadString("Asterisk", "MOHQueue", "");

                this.astIcon.Icon = new System.Drawing.Icon(@"../../phone.ico");
                this.astIcon.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(astIcon_MouseDoubleClick);
                this.astIcon.Visible = true;
            }
            catch (Exception exp)
            {
                myLogger.LogError(string.Format("Error loading to {0}. Error: {1}", "MainWindow", exp.Message), logging);
            }

            DeActivateControls();
            Loaded += new RoutedEventHandler(MainWindow_Loaded);
            //this.Closed += (s, e) => Application.Current.Shutdown();

        }
        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            dlgLogon astLogon = new dlgLogon();
            astLogon.Owner = this;
            astLogon.ShowDialog();

            if (astLogon.DialogResult.HasValue && astLogon.DialogResult.Value)
            {
                astHost = astLogon.Input[2];
                astPort = Convert.ToInt16(astLogon.Input[3]);
                astUser = astLogon.Input[0];
                astPass = astLogon.Input[1];
                astExtension = astLogon.Input[4];

                //new ManagerConnection(ASTERISK_HOST, ASTERISK_PORT, ASTERISK_LOGINNAME, ASTERISK_LOGINPWD);
                astCon = new ManagerConnection(astHost, astPort, astUser, astPass);
                try
                {
                    astCon.Login();
                    Console.WriteLine("Asterisk version : " + astCon.Version);
                    Console.WriteLine("Asterisk version : " + astCon.AsteriskVersion);
                    lblAsteriskVersion.Content = "Asterisk Version : " + astCon.AsteriskVersion + " - " + astCon.Version;
                    myLogger.LogInformation("Register Event astCon.NewState", logging);
                    astCon.NewState += new AsterNET.Manager.NewStateEventHandler(astCon_NewState);
                    // astCon.Link += new AsterNET.Manager.LinkEventHandler(astCon_Link);
                    myLogger.LogInformation("Register Event astCon.ConnectionState", logging);
                    //astCon.ConnectionState += new AsterNET.Manager.ConnectionStateEventHandler(astCon_ConnectionState);
                    // astCon.NewCallerId += new AsterNET.Manager.NewCallerIdEventHandler(astCon_NewCallerId);
                    //myLogger.LogInformation("Register Event astCon.Dial", logging);
                    //astCon.Dial += new DialEventHandler(astCon_Dial);
                    myLogger.LogInformation("Register Event astCon.Hangup", logging);
                    astCon.Hangup += new AsterNET.Manager.HangupEventHandler(astCon_Hangup);
                    myLogger.LogInformation("Register Event astCon.ExtensionStatus", logging);
                    astCon.ExtensionStatus += new ExtensionStatusEventHandler(astCon_ExtensionStatus);
                    myLogger.LogInformation("Register Event astCon.Hold", logging);
                    //astCon.Hold += new HoldEventHandler(astCon_Hold);
                    myLogger.LogInformation("Register Event astCon.HoldedCall", logging);
                    //astCon.HoldedCall += new HoldedCallEventHandler(astCon_HoldedCall);
                    myLogger.LogInformation("Register Event astCon.Join", logging);
                    //astCon.Join += new JoinEventHandler(astCon_Join);
                    myLogger.LogInformation("Register Event astCon.Leave", logging);
                    //astCon.Leave += new LeaveEventHandler(astCon_Leave);
                    myLogger.LogInformation("Register Event astCon.LogChannel", logging);
                    //astCon.LogChannel += new LogChannelEventHandler(astCon_LogChannel);
                    myLogger.LogInformation("Register Event astCon.Status", logging);
                    astCon.Status += new StatusEventHandler(astCon_Status);
                    myLogger.LogInformation("Register Event astCon.StatusComplete", logging);
                    astCon.StatusComplete += new StatusCompleteEventHandler(astCon_StatusComplete);
                    myLogger.LogInformation("Register Event astCon.Transfer", logging);
                    //astCon.Transfer += new TransferEventHandler(astCon_Transfer);
                    myLogger.LogInformation("Register Event astCon.MessageWaiting", logging);
                    //astCon.MessageWaiting += new MessageWaitingEventHandler(astCon_MessageWaiting);
                    myLogger.LogInformation("Register Event astCon.NewChannel", logging);
                    astCon.NewChannel += new NewChannelEventHandler(astCon_NewChannel);
                    myLogger.LogInformation("Register Event astCon.ParkedCall", logging);
                    astCon.ParkedCall += new ParkedCallEventHandler(astCon_ParkedCall);
                    myLogger.LogInformation("Register Event astCon.ParkedCallsComplete", logging);
                    astCon.ParkedCallsComplete += new ParkedCallsCompleteEventHandler(astCon_ParkedCallsComplete);
                    myLogger.LogInformation("Register Event astCon.ParkedCallTimeOut", logging);
                    astCon.ParkedCallTimeOut += new ParkedCallTimeOutEventHandler(astCon_ParkedCallTimeOut);
                    myLogger.LogInformation("Register Event astCon.ParkedCallsGiveUp", logging);
                    astCon.ParkedCallGiveUp += new ParkedCallGiveUpEventHandler(astCon_ParkedCallGiveUp);

                    astCon.QueueEntry += new QueueEntryEventHandler(astCon_QueueEntry);
                    astCon.QueueStatusComplete += new QueueStatusCompleteEventHandler(astCon_QueueStatusComplete);
                    astCon.QueueCallerAbandon += new QueueCallerAbandonEventHandler(astCon_QueueCallerAbandon);

                    label1.Content = "Please Wait";

                    myLogger.LogInformation("Starting Methode  GetHistory", logging);


                    GetHistory();
                    GetManagerUsers();

                    var toCheckVersion = astCon.Version.ToString().Split('.');
                    int iMainversion = Convert.ToInt16(toCheckVersion[0].ToString());
                    if (iMainversion >= 11)
                    {
                        GetPresencestate();
                    }
                    else
                    {
                        MessageBox.Show("For Presence State Asterisk Version 11 or higher is required!");
                    }
                    GetCustomPhonebook();
                    GetUsersDevices();
                    GetRingGroups();
                    GetChannelStatus();
                    GetAllUserPresenceStates();
                }
                catch (Exception ex)
                {
                    myLogger.LogError(string.Format("Error connecting to {0}. Error: {1}", astHost, ex.Message), logging);
                    MessageBox.Show(string.Format("Error connecting to {0}. Error: {1}", astHost, ex.Message));
                    Application.Current.Shutdown();
                }
                finally
                {
                    UpdateDataGrid();

                    myLogger.LogInformation(string.Format("Starting Timer UpdateDataGrid"), logging);
                    //myCountdownTimer.Interval = new TimeSpan(0, 0, 0, 0, 1000);
                    //myCountdownTimer.Tick += new EventHandler(myCountdownTimer_Tick);
                    //myCountdownTimer.Start();
                    myExtensionStateTimer.Interval = new TimeSpan(0, 0, 0, 0, 60000);
                    myExtensionStateTimer.Tick += new EventHandler(myExtensionStateTimer_Tick);
                    myExtensionStateTimer.Start();
                    label1.Content = "Connected";
                }
            }
            else
            {
                myLogger.LogInformation("Ending Application", logging);
                Application.Current.Shutdown();
            }
        }

        void MainWindow_Closed(object sender, EventArgs e)
        {
            SaveProperties();
            astIcon.Visible = false;
            //astCon.Logoff();
        }

        #endregion
        //*********************************** Tray Icon Mouse Buttons *************************************************
        #region Tray Icon
        void astIcon_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            this.WindowState = System.Windows.WindowState.Normal;
        }
        #endregion
        //*********************************** MainWindow Buttons *************************************************
        #region Buttons
        private void btnLogoff_Click(object sender, RoutedEventArgs e)
        {
            SetPrecenceState(astUser, "unavailable");
            astCon.Logoff();
            Application.Current.Shutdown();
        }

        private void btnDial_Click(object sender, RoutedEventArgs e)
        {
            DialNumber(textBoxToDial.Text);
        }

        private void btnHangup_Click(object sender, RoutedEventArgs e)
        {
            Disconnect(activeChannelSelected, activeChannelParty, activeUniqueId);
        }

        private void btnBlind_Click(object sender, RoutedEventArgs e)
        {
            GetChannelStatus();
            dlgTransfer astTransfer = new dlgTransfer();
            astTransfer.Owner = this;
            astTransfer.ShowDialog();
            if (astTransfer.DialogResult.HasValue && astTransfer.DialogResult.Value)
            {
                BlindTransfer(activeChannelParty, astTransfer.Input[0]);
            }
        }

        private void btnDialTheNumber(object sender, RoutedEventArgs e)
        {
            string sExtension;
            Button button = (Button)sender;
            DataGridRow selectedRow = DataGridRow.GetRowContainingElement(button);

            if (button.Content.ToString().Contains(astPeerType + "/"))
            {
                sExtension = button.Content.ToString().Remove(0, astPeerType.Length + 1);
            }
            else
            {
                sExtension = button.Content.ToString();
            }

            //sExtension = ((WpfAsteriskCTI.DataClasses.LocalExtension)(selectedRow.Item)).Extension.ToString();

            DialNumber(sExtension);
        }

        private void btnPageTheNumber(object sender, RoutedEventArgs e)
        {
            string sExtension;
            Button button = (Button)sender;
            DataGridRow selectedRow = DataGridRow.GetRowContainingElement(button);

            if (button.Content.ToString().Contains(astPeerType + "/"))
            {
                sExtension = button.Content.ToString().Remove(0, astPeerType.Length + 1);
            }
            else
            {
                sExtension = button.Content.ToString();
            }

            //sExtension = ((WpfAsteriskCTI.DataClasses.LocalExtension)(selectedRow.Item)).Extension.ToString();
            DialNumber("*80"+ sExtension);
        }

        private void btnPickupTheNumber(object sender, RoutedEventArgs e)
        {
            string sExtension;
            Button button = (Button)sender;
            DataGridRow selectedRow = DataGridRow.GetRowContainingElement(button);

            if (button.Content.ToString().Contains(astPeerType + "/"))
            {
                sExtension = button.Content.ToString().Remove(0, astPeerType.Length + 1);
            }
            else
            {
                sExtension = button.Content.ToString();
            }
            PickupParkedCall(sExtension);
        }

        private void btnHold_Click(object sender, RoutedEventArgs e)
        {
            Hold(activeChannelParty, "699");
        }

        private void btnPark_Click(object sender, RoutedEventArgs e)
        {
            Park();
        }

        private void btnMinimize_Click(object sender, RoutedEventArgs e)
        {
            this.WindowState = WindowState.Minimized;
        }

        private void btnClose_Click(object sender, RoutedEventArgs e)
        {
            SetPrecenceState(astUser, "unavailable");
            SaveProperties();
            astIcon.Visible = false;
            astCon.Logoff();
            Environment.Exit(0);
        }

        private void btnAdd_Click(object sender, RoutedEventArgs e)
        {
            int result = -1;
            dlgAddGlobalPhonebookEntry dlgAdd = new dlgAddGlobalPhonebookEntry("","","","","");
            dlgAdd.Owner = this;
            dlgAdd.ShowDialog();
            if (dlgAdd.DialogResult.HasValue && dlgAdd.DialogResult.Value)
            {
               result = InsertOrUpdateCustomPhonebook(dlgAdd.Input[0], dlgAdd.Input[1], dlgAdd.Input[2], dlgAdd.Input[3], dlgAdd.Input[4], astUser, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
               if (!(result >= 1))
               {
                   MessageBox.Show("Entry not added, please have a look into the LogFile!");
               }
            }

        }

        private void btnDeletePhonebook_Click(object sender, RoutedEventArgs e)
        {
            MessageBoxResult result = MessageBox.Show("Are you sure?","Delete Customer?", MessageBoxButton.OKCancel);
            if (result == MessageBoxResult.OK)
            {
                if (sender != null)
                {
                    string sPhone1 = ((WpfAsteriskCTI.DataClasses.CustomPhonebook)(dataGridGlobalPhonebook.SelectedItem)).Phone1.ToString();
                    string sId = ((WpfAsteriskCTI.DataClasses.CustomPhonebook)(dataGridGlobalPhonebook.SelectedItem)).Id.ToString();
                    DeleteCustomPhonebook(sId);
                }
            }
        }

        private void btnEditPhonebook_Click(object sender, RoutedEventArgs e)
        {
            if (sender != null)
            {
                int result = -1;
                string sCustomer = ((WpfAsteriskCTI.DataClasses.CustomPhonebook)(dataGridGlobalPhonebook.SelectedItem)).CustomerName.ToString();
                string sCompany = ((WpfAsteriskCTI.DataClasses.CustomPhonebook)(dataGridGlobalPhonebook.SelectedItem)).Company.ToString();
                string sPhone1 = ((WpfAsteriskCTI.DataClasses.CustomPhonebook)(dataGridGlobalPhonebook.SelectedItem)).Phone1.ToString();
                string sPhone2 = ((WpfAsteriskCTI.DataClasses.CustomPhonebook)(dataGridGlobalPhonebook.SelectedItem)).Phone2.ToString();
                string sMobile = ((WpfAsteriskCTI.DataClasses.CustomPhonebook)(dataGridGlobalPhonebook.SelectedItem)).Mobile_Phone.ToString();

                dlgAddGlobalPhonebookEntry dlgAdd = new dlgAddGlobalPhonebookEntry(sCustomer, sCompany, sPhone1, sPhone2, sMobile);

                dlgAdd.Owner = this;
                dlgAdd.ShowDialog();
                if (dlgAdd.DialogResult.HasValue && dlgAdd.DialogResult.Value)
                {
                    result = InsertOrUpdateCustomPhonebook(dlgAdd.Input[0], dlgAdd.Input[1], dlgAdd.Input[2], dlgAdd.Input[3], dlgAdd.Input[4], astUser, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                    if (!(result >= 1))
                    {
                        MessageBox.Show("Entry not added, please have a look into the LogFile!");
                    }
                }
            }
        }
        #endregion
        //*********************************** Asterisk Events **************************************************************
        #region Asterisk Events

        void astCon_QueueCallerAbandon(object sender, QueueCallerAbandonEvent e)
        {
            //DispatchItIfNeeded(() =>
            //{
            try
            {
                int found = -1;
                found = lstHold.IndexOf(lstHold.Where(x => x.UniqueID.Contains(e.UniqueId)).FirstOrDefault());
                if (found > -1)
                {
                    lstHold.RemoveAt(found);
                }
                else
                {

                }
            }
            catch (Exception exp)
            {

            }
            //});
        }

        void astCon_QueueStatusComplete(object sender, QueueStatusCompleteEvent e)
        {
            //throw new NotImplementedException();
        }

        void astCon_QueueEntry(object sender, QueueEntryEvent e)
        {
            int found = lstHold.IndexOf(lstHold.Where(x => x.Channel.Contains(e.Channel)).FirstOrDefault());
            if (found > -1)
            {
                var toUpdateNewState = lstHold.Where(x => x.Channel.Contains(e.Channel));
                foreach (var item in toUpdateNewState)
                {
                    item.Channel = e.Channel;
                    item.UniqueID = e.UniqueId;
                    item.CallerIdNum = e.Attributes["connectedlinenum"];
                    item.Queue = e.Queue;
                }
            }
            else
            {
                lstHold.Add(new DataClasses.Hold()
                {
                    Channel = e.Channel,
                    UniqueID = e.UniqueId,
                    CallerIdNum = e.Attributes["connectedlinenum"],
                    Queue = e.Queue 
                });
            }
            //throw new NotImplementedException();
        }

        void astCon_ParkedCall(object sender, ParkedCallEvent e)
        {
            this.Dispatcher.BeginInvoke(new Action(() => lstParkedCalls.Add(new DataClasses.ParkedCalls()
            {
                ActionId = e.ActionId,
                Attributes = e.Attributes,
                CallerId = e.CallerId,
                CallerIdName = e.CallerIdName,
                CallerIdNum = e.CallerIdNum,
                Channel = e.Channel,
                DateReceived = e.DateReceived,
                Exten = e.Exten,
                From = e.From,
                InternalActionId = e.InternalActionId,
                Privilege = e.Privilege,
                Server = e.Server,
                Source = e.Source,
                Timeout = e.Timeout,
                Timestamp = e.Timestamp,
                UniqueId = e.UniqueId
            })));
        }
        void astCon_ParkedCallsComplete(object sender, ParkedCallsCompleteEvent e)
        {
            //throw new NotImplementedException();
        }
        void astCon_ParkedCallTimeOut(object sender, ParkedCallTimeOutEvent e)
        {
           // throw new NotImplementedException();
        }
        void astCon_ParkedCallGiveUp(object sender, ParkedCallGiveUpEvent e)
        {
           // throw new NotImplementedException();
        }
        void astCon_NewChannel(object sender, NewChannelEvent e)
        {
            try
            {
                if (e.Attributes.Keys.Contains("exten"))
                {
                    DispatchItIfNeeded(() =>
                    {
                        lstNewChannel.Add(new DataClasses.NewChannel()
                        {
                            AccountCode = e.AccountCode,
                            //Attributes = e.Attributes,
                            CallerId = e.CallerId,
                            CallerIdName = e.CallerIdName,
                            CallerIdNum = e.CallerIdNum,
                            sPartyCallerIdNum = e.Attributes["exten"],
                            Channel = e.Channel,
                            ChannelState = e.ChannelState,
                            ChannelStateDesc = e.ChannelStateDesc,
                            //DateReceived = e.DateReceived,
                            //Privilege = e.Privilege,
                            //Server = e.Server,
                            //Source = e.Source,
                            State = e.State,
                            //TimeStamp = e.Timestamp,
                            UniqueId = e.UniqueId
                        });
                    });
                }
            }
            catch (Exception exp)
            {
                myLogger.LogError("astCon_NewChannel: " + exp.Message + "\r\nStacktrace: " + exp.StackTrace, logging);
            }
        }
        //void astCon_MessageWaiting(object sender, MessageWaitingEvent e)
        //{
        //    Debug.Print("astCon_StatusComplete: " + e.Mailbox);
        //}
        void astCon_Transfer(object sender, TransferEvent e)
        {
            Debug.Print("astCon_StatusComplete: " + e.SipCallId);
        }
        void astCon_StatusComplete(object sender, StatusCompleteEvent e)
        {
            Debug.Print("astCon_StatusComplete: " + e.Channel);
        }
        void astCon_Status(object sender, StatusEvent e)
        {
            try
            {
                var toSearch = e.UniqueId.Split('.');
                int found = lstNewState.IndexOf(lstNewState.Where(x => x.UniqueId.Contains(toSearch[0])).FirstOrDefault());
                if (found > -1)
                {
                    var toUpdateNewState = lstNewState.Where(x => x.UniqueId.Contains(toSearch[0]));
                    foreach (var item in toUpdateNewState)
                    {
                        if (e.CallerIdNum == astExtension && e.Attributes.ContainsKey("bridgedchannel"))
                        {
                            this.Dispatcher.BeginInvoke(new Action(() => item.Bridgedchannel = e.Attributes["bridgedchannel"]));
                            this.Dispatcher.BeginInvoke(new Action(() => item.Channel = e.Channel));
                        }
                        else
                        {
                            this.Dispatcher.BeginInvoke(new Action(() => item.Channel = e.Channel));
                        }
                        this.Dispatcher.BeginInvoke(new Action(() => item.DateReceived = e.DateReceived));
                        //this.Dispatcher.BeginInvoke(new Action(() => item.BridgedUniqueId = e.Attributes["bridgeduniqueid"]));
                        this.Dispatcher.BeginInvoke(new Action(() => item.UniqueId = e.UniqueId));
                    }
                }
                else
                {
                    if (e.Attributes["bridgedchannel"] == "SIP/" + astExtension || e.CallerIdNum == astExtension)
                    {
                        if ((e.State == "Up") || (e.State == "Ring") || (e.State == "Ringing") || (e.Attributes["channelstatedesc"] == "Up"))
                        {
                            this.Dispatcher.BeginInvoke(new Action(() => lstNewState.Add(new DataClasses.NewState()
                            {
                                //AccountCode = e.AccountCode,
                                Attributes = e.Attributes,
                                CallerId = e.CallerId,
                                CallerIdNum = e.CallerIdNum,
                                PartyCallerIdName = e.Attributes["connectedlinename"],
                                PartyCallerIdNum = e.Attributes["connectedlinenum"],
                                Channel = e.Channel,
                                Bridgedchannel = e.Attributes["bridgedchannel"],
                                DateReceived = e.DateReceived,
                                Privilege = e.Privilege,
                                Server = e.Server,
                                Source = e.Source,
                                State = e.State,
                                TimeStamp = e.Timestamp,
                                UniqueId = e.UniqueId,
                                BridgedUniqueId = e.Attributes["bridgeduniqueid"]
                            })));
                        }
                    }
                }
            }
            catch (Exception exp)
            {
                myLogger.LogError("astCon_Status: " + exp.Message + "\r\nStacktrace: " + exp.StackTrace, logging);
            }
            Debug.Print("astCon_Status: " + e.State);
        }
        //void astCon_LogChannel(object sender, LogChannelEvent e)
        //{
        //    Debug.Print("astCon_LogChannel: " + e.Channel);
        //}
        //void astCon_Leave(object sender, LeaveEvent e)
        //{
        //    Debug.Print("astCon_Leave: " + e.Channel);
        //}
        //void astCon_Join(object sender, JoinEvent e)
        //{
        //    Debug.Print("astCon_Join: " + e.Channel);
        //}
        //void astCon_HoldedCall(object sender, HoldedCallEvent e)
        //{
        //    Debug.Print("astCon_HoldedCall: " + e.Channel);
        //}
        //void astCon_Hold(object sender, HoldEvent e)
        //{
        //    Debug.Print("astCon_Hold: " + e.Channel);
        //}
        //void astCon_Dial(object sender, AsterNET.Manager.Event.DialEvent e)
        //{
        //    Debug.Print("astCon_Dial: " + e.Channel);
        //}
        //void astCon_NewCallerId(object sender, AsterNET.Manager.Event.NewCallerIdEvent e)
        //{
        //    this.Dispatcher.BeginInvoke(new Action(() => lstNewCalls.Add(new DataClasses.NewCall()
        //        {
        //            Attributes = e.Attributes,
        //            CallerId = e.CallerId,
        //            CallerIdName = e.CallerIdName,
        //            CallerIdNum = e.CallerIdNum,
        //            Channel = e.Channel,
        //            CidCallingPres = e.CidCallingPres,
        //            CidCallingPresNumeric = e.CidCallingPresNumeric,
        //            DateReceived = e.DateReceived,
        //            Privilege = e.Privilege,
        //            Server = e.Server,
        //            Source = e.Source,
        //            TimeStamp = e.Timestamp,
        //            UniqueId = e.UniqueId
                     
        //        })
        //     ));

        //    //dataGrid1.ItemsSource = lstNewCalls;
        //}
        //void astCon_ConnectionState(object sender, AsterNET.Manager.Event.ConnectionStateEvent e)
        //{
        //    Debug.Print("astCon_ConnectionState: " + e.Channel);
        //}
        //void astCon_Link(object sender, AsterNET.Manager.Event.LinkEvent e)
        //{
        //    Debug.Print("astCon_Link: " + e.CallerId1);
        //}
        void astCon_ExtensionStatus(object sender, AsterNET.Manager.Event.ExtensionStatusEvent e)
        {
            DispatchItIfNeeded(() =>
            {
                try
                {
                    var erg = lstLocalExtensions.Where(x => x.Extension == e.Exten);
                    foreach (var item in erg)
                    {
                       // item.Status = e.Status.ToString();
                        switch (e.Status)
                        {
                            case -1:
                                item.Status = "Extension not found";
                                break;
                            case -2:
                                item.Status = "Extension removed";
                                break;
                            case 0:
                                item.Status = "Idle";
                                break;
                            case 1:
                                item.Status = "In use";
                                break;
                            case 2:
                                item.Status = "Busy";
                                break;
                            case 4:
                                item.Status = "Unavailable";
                                break;
                            case 8:
                                item.Status = "Ringing";
                                break;
                            case 16:
                                item.Status = "On Hold";
                                break;
                            default:
                                item.Status = "undefinied";
                                break;
                        }
                    }

                }
                catch {}
            });
        }
        void astCon_Hangup(object sender, AsterNET.Manager.Event.HangupEvent e)
        {
            DispatchItIfNeeded(() =>
            {
                try
                {
                    int found = lstNewState.IndexOf(lstNewState.Where(x => x.UniqueId.Contains(e.UniqueId)).FirstOrDefault());
                    if (found > -1)
                    {
                        try
                        {
                            lstNewState.RemoveAt(found);
                            oldNumber = null;
                            newNumber = null;
                        }
                        catch (IndexOutOfRangeException exp)
                        {
                            myLogger.LogError("astCon_Hangup_IndexOutOfRangeException: " + exp.Message + "\r\nStacktrace: " + exp.StackTrace, logging);
                        }
                    }
                }
                catch (Exception exp)
                {
                    myLogger.LogError("astCon_Hangup: " + exp.Message + "\r\nStacktrace: " + exp.StackTrace, logging);
                }
                finally
                {
                    GetExtensionStateForAll();
                    GetHistory();
                    UpdateDataGrid();
                }
            });
        }
        void astCon_NewState(object sender, AsterNET.Manager.Event.NewStateEvent e)
        {
            myLogger.LogInformation("*********** astCon_NewState_START ", logging);
            try
            {
                if (e.ChannelStateDesc != null)
                {
                    //myLogger.LogInformation("astCon_NewState_e.ChannelStateDesc: " + e.ChannelStateDesc, logging);
                    //Debug.Print("New state: " + e.ChannelStateDesc);
                    if (e.Channel.ToUpper().StartsWith("SIP" + "/" + astExtension))
                    {
                        myLogger.LogInformation("astCon_NewState_e.Channel.ToUpper(): " + e.Channel.ToUpper(), logging);
                        // this event related to me
                        myLogger.LogInformation("astCon_NewState_e.ChannelStateDesc.ToLower(): " + e.ChannelStateDesc.ToLower(), logging);
                        switch (e.ChannelStateDesc.ToLower())
                        {
                            case "ring":
                                myLogger.LogInformation("astCon_NewState_ring: ", logging);
                                int index = lstNewChannel.IndexOf(lstNewChannel.Where(x => x.UniqueId.Contains(e.UniqueId)).FirstOrDefault());
                                myLogger.LogInformation("astCon_NewState_lstNewChannel.Index: " + index.ToString(), logging);
                                if (index > -1)
                                {
                                    DispatchItIfNeeded(() =>
                                    {
                                        lstNewState.Add(new DataClasses.NewState()
                                        {
                                            AccountCode = lstNewChannel[index].AccountCode,
                                            //Attributes = lstNewChannel[index].Attributes,
                                            CallerId = lstNewChannel[index].CallerId,
                                            CallerIdName = lstNewChannel[index].CallerIdName,
                                            CallerIdNum = lstNewChannel[index].CallerIdNum,
                                            PartyCallerIdNum = lstNewChannel[index].PartyCallerIdNum,
                                            Channel = lstNewChannel[index].Channel,
                                            ChannelState = lstNewChannel[index].ChannelState,
                                            ChannelStateDesc = lstNewChannel[index].ChannelStateDesc,
                                            DateReceived = e.DateReceived,
                                            Privilege = e.Privilege,
                                            Server = e.Server,
                                            Source = e.Source,
                                            State = lstNewChannel[index].State,
                                            TimeStamp = e.Timestamp,
                                            UniqueId = lstNewChannel[index].UniqueId
                                        });
                                    });
                                    myLogger.LogInformation("astCon_NewState_lstNewState.Count: " + lstNewState.Count.ToString(), logging);
                                }
                                myLogger.LogInformation("astCon_NewState_lstNewState.Count: " + lstNewState.Count.ToString(), logging);
                                break;

                            case "ringing":
                                myLogger.LogInformation("astCon_NewState_ringing: ", logging);
                                newNumber = e.CallerIdNum;
                                myLogger.LogInformation("astCon_NewState_oldNumber: " + newNumber, logging);
                                myLogger.LogInformation("astCon_NewState_newNumber: " + oldNumber, logging);
                                if (newNumber != oldNumber && e.Attributes.ContainsKey("connectedlinename") && e.Attributes.ContainsKey("connectedlinenum"))
                                {
                                    oldNumber = e.CallerIdNum;
                                    DispatchItIfNeeded(() =>
                                    {
                                        lstNewState.Add(new DataClasses.NewState()
                                        {
                                            AccountCode = e.AccountCode,
                                            Attributes = e.Attributes,
                                            PartyCallerIdNum = e.Attributes["connectedlinenum"],
                                            sPartyCallerIdName = e.Attributes["connectedlinename"],
                                            CallerId = e.CallerId,
                                            CallerIdName = e.CallerIdName,
                                            CallerIdNum = e.CallerIdNum,
                                            Channel = e.Channel,
                                            ChannelState = e.ChannelState,
                                            ChannelStateDesc = e.ChannelStateDesc,
                                            DateReceived = e.DateReceived,
                                            Privilege = e.Privilege,
                                            Server = e.Server,
                                            Source = e.Source,
                                            State = e.State,
                                            TimeStamp = e.Timestamp,
                                            UniqueId = e.UniqueId
                                        });
                                        myLogger.LogInformation("astCon_NewState_lstNewState.Count: " + lstNewState.Count.ToString(), logging);
                                    });
                                    myLogger.LogInformation("astCon_NewState_oldNumber: " + newNumber, logging);
                                    myLogger.LogInformation("astCon_NewState_newNumber: " + oldNumber, logging);
                                    myLogger.LogInformation("astCon_NewState_lstNewState.Count: " + lstNewState.Count.ToString(), logging);
                                }
                                #region
                                //myLogger.LogInformation("astCon_NewState ringing: " + toSearch[0].ToString(), logging);
                                //myLogger.LogInformation("astCon_NewState ringing var found: " + found.ToString(), logging);
                                //var toSearchID = e.UniqueId.Split('.');
                                //int foundID = lstNewState.IndexOf(lstNewState.Where(x => x.UniqueId.Contains(toSearch[0])).FirstOrDefault());
                                //if (foundID > -1)
                                //{
                                //    try
                                //    {
                                //        var toUpdateNewState = lstNewState.Where(x => x.UniqueId.Contains(toSearch[0]));
                                //        foreach (var item in toUpdateNewState)
                                //        {
                                //            this.Dispatcher.BeginInvoke(new Action(() => item.AccountCode = e.AccountCode));
                                //            this.Dispatcher.BeginInvoke(new Action(() => item.Attributes = e.Attributes));
                                //            this.Dispatcher.BeginInvoke(new Action(() => item.PartyCallerIdNum = e.Attributes["connectedlinenum"]));
                                //            this.Dispatcher.BeginInvoke(new Action(() => item.sPartyCallerIdName = e.Attributes["connectedlinename"]));
                                //            this.Dispatcher.BeginInvoke(new Action(() => item.CallerId = e.CallerId));
                                //            this.Dispatcher.BeginInvoke(new Action(() => item.CallerIdName = e.CallerIdName));
                                //            this.Dispatcher.BeginInvoke(new Action(() => item.CallerIdNum = e.CallerIdNum));
                                //            this.Dispatcher.BeginInvoke(new Action(() => item.Channel = e.Channel));
                                //            this.Dispatcher.BeginInvoke(new Action(() => item.ChannelState = e.ChannelState));
                                //            this.Dispatcher.BeginInvoke(new Action(() => item.ChannelStateDesc = e.ChannelStateDesc));
                                //            this.Dispatcher.BeginInvoke(new Action(() => item.DateReceived = e.DateReceived));
                                //            this.Dispatcher.BeginInvoke(new Action(() => item.Privilege = e.Privilege));
                                //            this.Dispatcher.BeginInvoke(new Action(() => item.Server = e.Server));
                                //            this.Dispatcher.BeginInvoke(new Action(() => item.Source = e.Source));
                                //            this.Dispatcher.BeginInvoke(new Action(() => item.State = e.State));
                                //            this.Dispatcher.BeginInvoke(new Action(() => item.TimeStamp = e.Timestamp));
                                //            this.Dispatcher.BeginInvoke(new Action(() => item.UniqueId = e.UniqueId));
                                //        }
                                //    }
                                //    catch (Exception exp)
                                //    {
                                //        myLogger.LogError("astCon_NewState_ringing found > -1 : " + exp.Message + "\r\nStacktrace: " + exp.StackTrace, logging);
                                //    }
                                //}
                                //else
                                //{
                                //    try
                                //    {
                                //        string sBallonInfo = "Incoming call from \r\nNumber: " + e.Attributes["connectedlinenum"] + "\r\nName: " + e.Attributes["connectedlinename"];
                                //        this.astIcon.ShowBalloonTip(500, "Information", sBallonInfo, System.Windows.Forms.ToolTipIcon.Info);
                                //        myNotifyTimer.Interval = new TimeSpan(0, 0, 0, 0, 2000);
                                //        myNotifyTimer.Tick += new EventHandler(myNotifyTimer_Tick);
                                //        myNotifyTimer.Start();
                                //    }
                                //    catch (Exception ex)
                                //    {
                                //        myLogger.LogError(string.Format("Inizialize {0}. Error: {1}", "BallonInfo", ex.Message), logging);
                                //    }

                                //    try
                                //    {
                                //        if (oldNumber != newNumber)
                                //        {
                                //            oldNumber = newNumber;
                                //            this.Dispatcher.BeginInvoke(new Action(() => lstNewState.Add(new DataClasses.NewState()
                                //            {
                                //                AccountCode = e.AccountCode,
                                //                Attributes = e.Attributes,
                                //                PartyCallerIdNum = e.Attributes["connectedlinenum"],
                                //                sPartyCallerIdName = e.Attributes["connectedlinename"],
                                //                CallerId = e.CallerId,
                                //                CallerIdName = e.CallerIdName,
                                //                CallerIdNum = e.CallerIdNum,
                                //                Channel = e.Channel,
                                //                ChannelState = e.ChannelState,
                                //                ChannelStateDesc = e.ChannelStateDesc,
                                //                DateReceived = e.DateReceived,
                                //                Privilege = e.Privilege,
                                //                Server = e.Server,
                                //                Source = e.Source,
                                //                State = e.State,
                                //                TimeStamp = e.Timestamp,
                                //                UniqueId = e.UniqueId
                                //            })));
                                //        }
                                //    }
                                //    catch (Exception exp)
                                //    {
                                //        myLogger.LogError("astCon_NewState_ ringing else tree: " + exp.Message + "\r\nStacktrace: " + exp.StackTrace, logging);
                                //    }
                                //}
                                #endregion
                                break;

                            case "up":
                                myLogger.LogInformation("astCon_NewState_up: ", logging);
                                if (e.Attributes.ContainsKey("connectedlinename") && e.Attributes.ContainsKey("connectedlinenum"))
                                {
                                    oldNumber = null;
                                    DispatchItIfNeeded(() =>
                                    {
                                        lstNewState.Clear();
                                        lstNewState.Add(new DataClasses.NewState()
                                        {
                                            AccountCode = e.AccountCode,
                                            Attributes = e.Attributes,
                                            PartyCallerIdNum = e.Attributes["connectedlinenum"],
                                            sPartyCallerIdName = e.Attributes["connectedlinename"],
                                            CallerId = e.CallerId,
                                            CallerIdName = e.CallerIdName,
                                            CallerIdNum = e.CallerIdNum,
                                            Channel = e.Channel,
                                            ChannelState = e.ChannelState,
                                            ChannelStateDesc = e.ChannelStateDesc,
                                            DateReceived = e.DateReceived,
                                            Privilege = e.Privilege,
                                            Server = e.Server,
                                            Source = e.Source,
                                            State = e.State,
                                            TimeStamp = e.Timestamp,
                                            UniqueId = e.UniqueId
                                        });
                                        myLogger.LogInformation("astCon_NewState_lstNewState.Count: " + lstNewState.Count.ToString(), logging);
                                    });
                                }
                                else
                                {
                                    oldNumber = null;
                                    DispatchItIfNeeded(() =>
                                    {
                                        lstNewState.Clear();
                                        lstNewState.Add(new DataClasses.NewState()
                                        {
                                            AccountCode = e.AccountCode,
                                            Attributes = e.Attributes,
                                            PartyCallerIdNum = numberToDial,
                                            sPartyCallerIdName = numberToDial,
                                            CallerId = e.CallerId,
                                            CallerIdName = e.CallerIdName,
                                            CallerIdNum = e.CallerIdNum,
                                            Channel = e.Channel,
                                            ChannelState = e.ChannelState,
                                            ChannelStateDesc = e.ChannelStateDesc,
                                            DateReceived = e.DateReceived,
                                            Privilege = e.Privilege,
                                            Server = e.Server,
                                            Source = e.Source,
                                            State = e.State,
                                            TimeStamp = e.Timestamp,
                                            UniqueId = e.UniqueId
                                        });
                                        myLogger.LogInformation("astCon_NewState_lstNewState.Count: " + lstNewState.Count.ToString(), logging);
                                    });
                                }
                                myLogger.LogInformation("astCon_NewState_oldNumber: " + newNumber,logging);
                                myLogger.LogInformation("astCon_NewState_newNumber: " + oldNumber,logging);

                                break;

                            default:
                                break;
                        }
                    }
                }
            }
            catch (Exception exp)
            {
                myLogger.LogError("astCon_NewState_Exception: " + exp.Message + "\r\nStacktrace: " + exp.StackTrace, logging);
            }
            finally
            {
                myLogger.LogInformation("astCon_NewState_UpdateDataGrid: ", logging);
                UpdateDataGrid();
                myLogger.LogInformation("*********** astCon_NewState_END ", logging);
            }
        }
        #endregion     
        //*********************************** Private Methods **********************************************************
        #region private methods 

        private void GetAllUserPresenceStates()
        {
            foreach (var item in lstUserPresencestate)
            {
                var sStatus = GetPrecenceState(item.User).Split(',');

                int iCount = sStatus.Count();

                int foundUser = lstUserPresencestate.IndexOf(lstUserPresencestate.Where(x => x.User.Contains(item.User)).FirstOrDefault());
                if (foundUser > -1)
                {
                    var toUpdate = lstUserPresencestate.Where(x => x.User.Contains(item.User));
                    foreach (var item1 in toUpdate)
                    {
                        if (iCount >= 1)
                        {
                            item1.State = sStatus[0].ToString();
                        }
                        if (iCount >= 2)
                        {
                            item1.Subject = sStatus[1].ToString();
                        }
                        if (iCount >= 3)
                        {
                            item1.Message = sStatus[2].ToString();
                        }
                        item1.State = sStatus[0];
                    }
                }
            }
        }
        /// <summary>
        /// Reads the Presence Status 
        /// </summary>
        /// <param name="Variable">CustomPresence:Living Room</param> 
        /// <param name="Value">away,In the batcave, Making a new batch of batarangs</param>
        private string GetPrecenceState(string UserName)
        {
            string Status = "not available";

            string Variable = "CustomPresence:" + UserName + ",value";
            GetVarAction psa = new GetVarAction("PRESENCE_STATE(" + Variable + ")");
            //psa.Variable = "PRESENCE_STATE(" + Variable + ")";

            try
            {
                ManagerResponse mr = astCon.SendAction(psa, 30000);
                if (mr.Response == "Success" && mr.Attributes.ContainsKey("value"))
                {
                    Status = mr.Attributes["value"].ToString();
                    Console.WriteLine("PresenceStateActionSetvar" + "\n\tResponse:" + mr.Response + "\n\tMessage:" + mr.Message + mr.Attributes);

                }

                Variable = "CustomPresence:" + UserName + ",subtype";
                psa = new GetVarAction("PRESENCE_STATE(" + Variable + ")");
                mr = astCon.SendAction(psa, 30000);
                if (mr.Response == "Success" && mr.Attributes.ContainsKey("value"))
                {
                    Status = Status + "," + mr.Attributes["value"].ToString();
                    Console.WriteLine("PresenceStateActionSetvar" + "\n\tResponse:" + mr.Response + "\n\tMessage:" + mr.Message + mr.Attributes);
                }


                Variable = "CustomPresence:" + UserName + ",message";
                psa = new GetVarAction("PRESENCE_STATE(" + Variable + ")");
                mr = astCon.SendAction(psa, 30000);
                if (mr.Response == "Success" && mr.Attributes.ContainsKey("value"))
                {
                    Status = Status = Status + "," + mr.Attributes["value"].ToString();
                    Console.WriteLine("PresenceStateActionSetvar" + "\n\tResponse:" + mr.Response + "\n\tMessage:" + mr.Message + mr.Attributes);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return Status;
        }
        /// <summary>
        /// Sets a PresenceStatus 
        /// </summary>
        /// <param name="Variable">CustomPresence:Living Room</param> 
        /// <param name="Value">away,In the batcave, Making a new batch of batarangs</param>
        private void SetPrecenceState(string UserName, string Value)
        {
            DispatchItIfNeeded(() =>
            {
                string Variable = "PRESENCE_STATE(CustomPresence:" + UserName + ")";
                SetVarAction psa = new SetVarAction(Variable, Value);

                try
                {
                    ManagerResponse mr = astCon.SendAction(psa, 30000);
                    Console.WriteLine("PresenceStateActionSetvar" + "\n\tResponse:" + mr.Response + "\n\tMessage:" + mr.Message + mr.Attributes);
                    //status = ((AsterNET.Manager.Response.ExtensionStateResponse)(mr)).Status;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            });
        }
        /// <summary>
        /// Get Extension and Trunks from Asterisk will be changed later to use the Database function
        /// </summary>
        private void GetExtensions()
        {
            bool bCheckDial = false;
            bool bCheckcontext = false;
            bool bCallerid = false;
            GetConfigAction gc = new GetConfigAction("sip_additional.conf");
            try
            {
                String category = null;
                String dialstring = null;
                String callerid = null;

                ManagerResponse mr = astCon.SendAction(gc, 30000);

                foreach (var item in mr.Attributes)
                {
                    if (item.ToString().Contains("category"))
                    {
                        category = item.Value.ToString();
                        bCheckDial = true;
                        bCheckcontext = true;
                    }

                    if ((bCheckDial == true) && (item.ToString().Contains("dial")))
                    {
                        dialstring = item.Value.ToString();
                        bCallerid = true;
                    }

                    if ((bCallerid == true) && (item.ToString().Contains("callerid")))
                    {
                        callerid = item.Value.ToString();
                        lstLocalExtensions.Add(new DataClasses.LocalExtension()
                            {
                                Extension = category,
                                Dial = dialstring.Remove(0, 5),
                                Callerid = callerid.Remove(0, 9)
                            });


                        bCallerid = false;
                        bCheckDial = false;
                        bCheckcontext = false;
                    }

                    if ((bCheckcontext == true) && (item.ToString().Contains("from-trunk")))
                    {
                        lstTrunks.Add(new DataClasses.Trunks()
                            {
                                Dial = category
                            });
                        bCallerid = false;
                        bCheckDial = false;
                        bCheckcontext = false;
                    }
                }

                Console.WriteLine("Hangup Call" + "\n\tResponse:" + mr.Response + "\n\tMessage:" + mr.Message + mr.Attributes);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                dataGridLocalExtension.ItemsSource = lstLocalExtensions;
                dataGridTrunks.ItemsSource = lstTrunks;
            }

        }
        /// <summary>
        /// Get Status of Extension
        /// </summary>
        /// <param name="sExtension"></param>
        /// <returns></returns>
        private int GetExtensionState(string sExtension)
        {
            int status = -1;
            ExtensionStateAction esa = new ExtensionStateAction();
            esa.Exten = sExtension;
            esa.Context = "default";
            try
            {

                ManagerResponse mr = astCon.SendAction(esa, 30000);
                Console.WriteLine("OriginateAction" + "\n\tResponse:" + mr.Response + "\n\tMessage:" + mr.Message + mr.Attributes);
                status = ((AsterNET.Manager.Response.ExtensionStateResponse)(mr)).Status;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return status;
        }
        /// <summary>
        /// Gets all Status for All extensions and convert it to a Textmessage
        /// </summary>
        private void GetExtensionStateForAll()
        {
            DispatchItIfNeeded(() =>
            {
                foreach (var item in lstLocalExtensions)
                {
                    int status = GetExtensionState(item.Extension);
                    foreach (var itemToChange in lstLocalExtensions.Where(x => x.Extension == item.Extension))
                    {
                        itemToChange.Extension = item.Extension;

                        switch (status)
                        {
                            case -1:
                                itemToChange.Status = "Extension not found";
                                break;
                            case -2:
                                itemToChange.Status = "Extension removed";
                                break;
                            case 0:
                                itemToChange.Status = "Idle";
                                break;
                            case 1:
                                itemToChange.Status = "In use";
                                break;
                            case 2:
                                itemToChange.Status = "Busy";
                                break;
                            case 4:
                                itemToChange.Status = "Unavailable";
                                break;
                            case 8:
                                itemToChange.Status = "Ringing";
                                break;
                            case 16:
                                itemToChange.Status = "On Hold";
                                break;
                            default:
                                itemToChange.Status = status.ToString();
                                break;
                        }

                    }
                }
            });
        }
        /// <summary>
        /// Dials the Number, numberToCall = Destination, direction = inbound or outbound
        /// </summary>
        /// <param name="numberToCall"></param>
        /// <param name="direction"></param>
        private void DialNumber(string numberToCall)
        {
            numberToDial = numberToCall;
            numberToCall = numberToCall.Replace(" ", "");
            string sBallonInfo = "Dialing \r\nNumber: " + numberToCall;
            this.astIcon.ShowBalloonTip(500, "Information", sBallonInfo, System.Windows.Forms.ToolTipIcon.Info);
            myNotifyTimer.Interval = new TimeSpan(0, 0, 0, 0, 2000);
            myNotifyTimer.Tick += new EventHandler(myNotifyTimer_Tick);
            myNotifyTimer.Start();  

            OriginateAction oa = new OriginateAction();

            var foundLocalExtension = lstLocalExtensions.FirstOrDefault(y => y.Extension == numberToCall);
            var foundLocalRingGroup = lstRingGroups.FirstOrDefault(y => y.Grpum == numberToCall);


            if (foundLocalExtension != null)
            {
                oa.Context = "default";
                oa.Priority = "1";
                oa.Exten = astExtension; // The extention where the call goes if Asterisk is able to do the call
                oa.CallerId = astCallerId; // CallerID to use for the call
                oa.Channel = astPeerType + "/" + numberToCall;
            }
            else  if (foundLocalRingGroup != null)
            {
                oa.Context = "default";
                oa.Priority = "1";
                oa.Exten = astExtension; // The extention where the call goes if Asterisk is able to do the call
                oa.CallerId = astCallerId; // CallerID to use for the call
                oa.Channel = "LOCAL" + "/" + numberToCall + "@from-internal";
            }
            else if (numberToCall.Contains("*80"))
            {
                oa.Context = "default";
                oa.Priority = "1";
                oa.Exten = astExtension; // The extention where the call goes if Asterisk is able to do the call
                oa.CallerId = astCallerId; // CallerID to use for the call
                oa.Channel = "LOCAL" + "/" + numberToCall + "@ext-intercom";
            }
            else
            {
                // As per latest updates in Asterisk 1.8 if you are originating on external peer/trunk then channel variable will be like SIP/peer/extension instead of SIP/extension@peer

                oa.Context = "from-internal";
                oa.Priority = "1";
                oa.Exten = numberToCall; // The extention where the call goes if Asterisk is able to do the call
                oa.CallerId = astCallerId; // CallerID to use for the call
                oa.Channel = "SIP" + "/" + astExtension;

                // Autoanswer for Polycom script
                //oa.Context = "from-internal";
                //oa.Priority = "1";
                //oa.Exten = numberToCall; // The extention where the call goes if Asterisk is able to do the call
                //oa.CallerId = astCallerId; // CallerID to use for the call
                //oa.Channel = "LOCAL" + "/*80" + astExtension + "@ext-intercom";
               
            }

            oa.Timeout = 30000;
            oa.Async = true;

            try
            {
                ManagerResponse mr = astCon.SendAction(oa, oa.Timeout);
                Console.WriteLine("OriginateAction" + "\n\tResponse:" + mr.Response + "\n\tMessage:" + mr.Message + mr.Attributes);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        /// <summary>
        /// Disconnects the given channel, and removes it from the NewState list
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="party"></param>
        /// <param name="sUniqueId"></param>
        private void Disconnect(string channel, string party, string sUniqueId)
        {
            try
            {
                HangupAction ha = new HangupAction();
                ha.Channel = channel;
                try
                {
                    ManagerResponse mr = astCon.SendAction(ha, 10000);
                    Console.WriteLine("Hangup Call" + "\n\tResponse:" + mr.Response + "\n\tMessage:" + mr.Message);
                    if (mr.Response == "Success")
                    {
                        var vUniqueId = sUniqueId.Split('.');

                        foreach (var itemToRemove in lstNewState.Where(x => x.UniqueId.StartsWith(vUniqueId[0].ToString())))
                        {
                            this.Dispatcher.BeginInvoke(new Action(() => lstNewState.Remove(itemToRemove)));
                        }
                        //foreach (var itemToRemove in lstNewCalls.Where(x => x.UniqueId.StartsWith(vUniqueId[0].ToString())))
                        //{
                        //    this.Dispatcher.BeginInvoke(new Action(() => lstNewCalls.Remove(itemToRemove)));
                        //}
                        //foreach (var itemToRemove in lstNewCalls.Where(x => x.UniqueId.StartsWith(vUniqueId[0].ToString())))
                        //{
                        //    this.Dispatcher.BeginInvoke(new Action(() => lstNewCalls.Remove(itemToRemove)));
                        //}
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
            catch { }
        }
        /// <summary>
        /// Transfers the given channel to Destination
        /// Params: Channel = channel to Transfer, sDestination = Number to Transfer to
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="sDestination"></param>
        private void BlindTransfer(string channel, string sDestination)
        {
            try
            {
                RedirectAction ra = new RedirectAction();
                ra.Context = "default";
                ra.Channel = channel;
                ra.Exten = sDestination;
                ra.Priority = 1;
                try
                {
                    ManagerResponse mr = astCon.SendAction(ra, 10000);
                    Console.WriteLine("Transfer Call" + "\n\tResponse:" + mr.Response + "\n\tMessage:" + mr.Message);
                }
                catch (Exception ex)
                {
                    myLogger.LogError(string.Format("Error loading to {0}. Error: {1}", "BlindTransfer Satus", ex.Message), logging);
                    Console.WriteLine(ex.Message);
                }
            }
            catch { }
        }
        /// <summary>
        /// Parks the Call for the given Time
        /// </summary>
        private void Park()
        {
            //GetChannelStatus();

            dlgParkCall astParkCall = new dlgParkCall();

            astParkCall.Owner = this;
            astParkCall.ShowDialog();


            if (astParkCall.DialogResult.HasValue && astParkCall.DialogResult.Value)
            {
                ParkAction pa = new ParkAction(activeChannelParty, activeChannelUp, astParkCall.Input[1], astParkCall.Input[0]);
                try
                {
                    ManagerResponse mr = astCon.SendAction(pa, 30000);
                    Console.WriteLine("Park Call" + "\n\tResponse:" + mr.Response + "\n\tMessage:" + mr.Message);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
        }
        /// <summary>
        /// PicksUp a Parked Call
        /// </summary>
        /// <param name="sExtension"></param>
        private void PickupParkedCall(string sExtension)
        {
            OriginateAction oa = new OriginateAction();
            oa.Application = "ParkedCall";
            //oa.Channel = "SIP/10";
            oa.Channel = astPeerType + "/" + astExtension;
            //oa.Exten = "71";
            oa.Exten = sExtension;
            // oa.Data = "71";
            // oa.Context = "default";
            oa.CallerId = "Parked Call " + oa.Exten;
            oa.Async = true;
            oa.Timeout = 30000;
            oa.Async = true;
            try
            {
                ManagerResponse mr = astCon.SendAction(oa, oa.Timeout);
                Console.WriteLine("OriginateAction" + "\n\tResponse:" + mr.Response + "\n\tMessage:" + mr.Message + mr.Attributes);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                GetChannelStatus();
            }
           
        }
        /// <summary>
        /// Get all aktive channels, this will trigger the Status Event
        /// </summary>
        private void GetChannelStatus()
        {
            StatusAction sa = new StatusAction();
            try
            {
                ManagerResponse mr = astCon.SendAction(sa, 10000);
                Console.WriteLine("Transfer Call" + "\n\tResponse:" + mr.Response + "\n\tMessage:" + mr.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        /// <summary>
        /// Updates all Datagrids
        /// </summary>
        private void UpdateDataGrid()
        {
            DispatchItIfNeeded(() =>
            {
                dataGridGlobalPhonebook.ItemsSource = lstCustomPhonebook;
                dataGridUserPresence.ItemsSource = lstUserPresencestate;
                dataGridNewState.ItemsSource = lstNewState;
                dataGridHistory.ItemsSource = lstHistory;
                dataGridParkedCalls.ItemsSource = lstParkedCalls;
                dataGridRingGroups.ItemsSource = lstRingGroups;
                dataGridLocalExtension.ItemsSource = lstLocalExtensions;
            });
        }
        /// <summary>
        /// activate all Buttons
        /// </summary>
        private void ActivateControls()
        {
            btnHangup.IsEnabled = true;
           // btnHold.IsEnabled = true;
            btnTransfer.IsEnabled = true;
            btnPark.IsEnabled = true;
        }
        /// <summary>
        /// deaktivate all Buttons
        /// </summary>
        private void DeActivateControls()
        {
            btnHangup.IsEnabled = false;
           // btnHold.IsEnabled = false;
            btnTransfer.IsEnabled = false;
            btnPark.IsEnabled = false;
        }
        /// <summary>
        /// sends a Call to Hold Queue (this is not done yet finally)
        /// </summary>
        /// <param name="channel"></param>
        private void Hold(string channel, string sMOHExtension)
        {
            DispatchItIfNeeded(() =>
            {
                try
                {
                    RedirectAction ra = new RedirectAction();
                    ra.Context = "default";
                    ra.Channel = channel;
                    // ra.ExtraChannel = "SIP/700";
                    ra.Exten = sMOHExtension;
                    ra.Priority = 1;
                    try
                    {
                        ManagerResponse mr = astCon.SendAction(ra, 10000);
                        Console.WriteLine("Transfer Call" + "\n\tResponse:" + mr.Response + "\n\tMessage:" + mr.Message);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                    finally
                    {
                        lstHold.Add(new DataClasses.Hold()
                        {
                            Channel = ra.Channel
                        });
                    }
                }
                catch { }
            });
        }
        /// <summary>
        /// should give the Queue Status of the given Queue, but this is not working, maybe an API or Asterisk issue.
        /// The Methode will always Timeout if calls were in the Queue.
        /// </summary>
        /// <param name="sQueue"></param>
        /// 
        private void QueueStatus(string sQueue)
        {
            DispatchItIfNeeded(() =>
            {
                QueueStatusAction qsa = new QueueStatusAction();
                qsa.Queue = sQueue;
                try
                {
                    ManagerResponse mr = astCon.SendAction(qsa, 30000);
                    Console.WriteLine("Queue Status" + "\n\tResponse:" + mr.Response + "\n\tMessage:" + mr.Message);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            });
        }

        /// <summary>
        /// Dispatcher
        /// </summary>
        /// <param name="action"></param>
        public void DispatchItIfNeeded(Action action)
        {
            if (!Dispatcher.CheckAccess())
            {
                Dispatcher.BeginInvoke(action);
            }
            else
            {
                action.Invoke();
            }
        }
        public void SaveProperties()
        {
            //***************************************************************** Splitter ******************************************

            if (Properties.Settings.Default.Splitter == null)
            {
                Properties.Settings.Default.Splitter = new double();
            }
            Properties.Settings.Default.Splitter = column1.Width.Value;

            //***************************************************************** NewState ******************************************
            if (Properties.Settings.Default.ColumnOrdersNewState == null)
            {
                Properties.Settings.Default.ColumnOrdersNewState = new System.Collections.Specialized.StringCollection();
            }
            Properties.Settings.Default.ColumnOrdersNewState.Clear();

            if (Properties.Settings.Default.ColumnSizeNewState == null)
            {
                Properties.Settings.Default.ColumnSizeNewState = new System.Collections.Specialized.StringCollection();
            }
            Properties.Settings.Default.ColumnSizeNewState.Clear();

            if (Properties.Settings.Default.ColumnNewStateVisiblity == null)
            {
                Properties.Settings.Default.ColumnNewStateVisiblity = new System.Collections.Specialized.StringCollection();
            }
            Properties.Settings.Default.ColumnNewStateVisiblity.Clear();

            foreach (var col in dataGridNewState.Columns)
            {
                Properties.Settings.Default.ColumnOrdersNewState.Add(col.DisplayIndex.ToString());
                Properties.Settings.Default.ColumnSizeNewState.Add(col.ActualWidth.ToString());
                Properties.Settings.Default.ColumnNewStateVisiblity.Add(col.Visibility.ToString());
            }
            Properties.Settings.Default.Save();

            //***************************************************************** History *******************************************

            if (Properties.Settings.Default.ColumnOrdersHistory == null)
            {
                Properties.Settings.Default.ColumnOrdersHistory = new System.Collections.Specialized.StringCollection();
            }
            Properties.Settings.Default.ColumnOrdersHistory.Clear();

            if (Properties.Settings.Default.ColumnHistoryStateVisiblity == null)
            {
                Properties.Settings.Default.ColumnHistoryStateVisiblity = new System.Collections.Specialized.StringCollection();
            }
            Properties.Settings.Default.ColumnHistoryStateVisiblity.Clear();


            if (Properties.Settings.Default.ColumnSizeHistory == null)
            {
                Properties.Settings.Default.ColumnSizeHistory = new System.Collections.Specialized.StringCollection();
            }
            Properties.Settings.Default.ColumnSizeHistory.Clear();

            foreach (var col in dataGridHistory.Columns)
            {
                Properties.Settings.Default.ColumnOrdersHistory.Add(col.DisplayIndex.ToString());
                Properties.Settings.Default.ColumnSizeHistory.Add(col.ActualWidth.ToString());
                Properties.Settings.Default.ColumnHistoryStateVisiblity.Add(col.Visibility.ToString());
            }
            Properties.Settings.Default.Save();
        }
        public void LoadProperties()
        {
            //***************************************************************** Splitter ******************************************


            column1.Width = new GridLength(Properties.Settings.Default.Splitter);


            //***************************************************************** NewState ******************************************

            if (Properties.Settings.Default.ColumnOrdersNewState != null)
            {
                for (int j = 0; j < Properties.Settings.Default.ColumnOrdersNewState.Count; j++)
                {
                    int index = Convert.ToInt32(Properties.Settings.Default.ColumnOrdersNewState[j]);
                    dataGridNewState.Columns[j].DisplayIndex = index;

                    double dsize = Convert.ToDouble(Properties.Settings.Default.ColumnSizeNewState[j]);
                    dataGridNewState.Columns[j].Width = dsize;

                    var visibility = Properties.Settings.Default.ColumnNewStateVisiblity[j];
                    if (visibility == "Visible")
                    {
                        dataGridNewState.Columns[j].Visibility = System.Windows.Visibility.Visible;
                        ((System.Windows.Controls.CheckBox)(cmNewState.Items[j])).IsChecked = true;
                    }
                    else
                    {
                        dataGridNewState.Columns[j].Visibility = System.Windows.Visibility.Hidden;
                        ((System.Windows.Controls.CheckBox)(cmNewState.Items[j])).IsChecked = false;
                    }

                }
            }

            //***************************************************************** History ******************************************

            if (Properties.Settings.Default.ColumnOrdersHistory != null)
            {
                for (int j = 0; j < Properties.Settings.Default.ColumnOrdersHistory.Count; j++)
                {
                    int index = Convert.ToInt32(Properties.Settings.Default.ColumnOrdersHistory[j]);
                    dataGridHistory.Columns[j].DisplayIndex = index;

                    double dsize = Convert.ToDouble(Properties.Settings.Default.ColumnSizeHistory[j]);
                    dataGridHistory.Columns[j].Width = dsize;

                    var visibility = Properties.Settings.Default.ColumnHistoryStateVisiblity[j];
                    if (visibility == "Visible")
                    {
                        dataGridHistory.Columns[j].Visibility = System.Windows.Visibility.Visible;
                        ((System.Windows.Controls.CheckBox)(cmHistory.Items[j])).IsChecked = true;
                    }
                    else
                    {
                        dataGridHistory.Columns[j].Visibility = System.Windows.Visibility.Hidden;
                        ((System.Windows.Controls.CheckBox)(cmHistory.Items[j])).IsChecked = false;
                    }
                }
            }
        }
        #endregion
        //*********************************** Timer ***********************************************************
        #region Timer
        private void myCountdownTimer_Tick(object sender, EventArgs e)
        {
           UpdateDataGrid();
        }
        private void myNotifyTimer_Tick(object sender, EventArgs e)
        {
            myNotifyTimer.Stop();
            astIcon.Visible = false;
            astIcon.Visible = true;
        }
        private void myExtensionStateTimer_Tick(object sender, EventArgs e)
        {
            GetAllUserPresenceStates();
            UpdateDataGrid();
            GetExtensionStateForAll();
        }
        #endregion
        //*********************************** Database Actions *********************************************************
        #region DatabaseActions
        private int InsertOrUpdateCustomPhonebook(string sCustomer, string sCompany, string sPhone1, string sPhone2, string sMobile, string sModifiedBy, string sModified )
        {
            int result = 0;
            string sIdToChange = "-1";
            string sPath = System.AppDomain.CurrentDomain.BaseDirectory;
            sPath = sPath + "Configuration\\config.ini";
            cIniReader _ini = new cIniReader(sPath);
            string mysqlconnection = _ini.ReadString("Database", "ConnectionStringAsterisk", "");
            myLogger.LogInformation("ConnectionString: " + mysqlconnection, logging);
            MySqlConnection connection = new MySqlConnection(mysqlconnection);
            connection.Open();
            
            string sql = "SELECT * FROM asterisk.custom_phonebook where phone1 = '"+ sPhone1 +"' AND customer_name = '"+ sCustomer +"'";
            MySqlCommand insertorupdateCommand = new MySqlCommand(sql, connection);

            try
            {
                MySqlDataReader rdr = insertorupdateCommand.ExecuteReader();
                while (rdr.Read())
                {
                    sIdToChange = rdr["id"].ToString();
                    result++;
                }
            }
            catch (Exception exp)
            {
                myLogger.LogError("InsertOrUpdateCustomPhonebook: " + exp.Message + "\r\nStacktrace: " + exp.StackTrace, logging);
            }
            finally
            {
                connection.Close();
            }

            if (result >= 1)
            {
                sql = "UPDATE asterisk.custom_phonebook SET customer_name = '" + sCustomer + "', company = '" + sCompany + "', phone1 = '" + sPhone1 + "', phone2 = '" + sPhone2 + "', mobile_phone = '" + sMobile + "', modifiedby = '" + sModifiedBy + "', modified = '" + sModified + "' WHERE id = '" + sIdToChange + "';";
            }
            else
            {
                sql = "INSERT INTO asterisk.custom_phonebook (customer_name, company, phone1, phone2, mobile_phone, modifiedby, modified) VALUES ('" + sCustomer + "', '" + sCompany + "', '" + sPhone1 + "', '" + sPhone2 + "', '" + sMobile + "', '" + sModifiedBy + "', '" + sModified + "');";
            }

            connection.Open();
            insertorupdateCommand = new MySqlCommand(sql, connection);
            try
            {
                result = insertorupdateCommand.ExecuteNonQuery();
            }
            catch (Exception exp)
            {
                myLogger.LogError("InsertOrUpdateCustomPhonebook: " + exp.Message + "\r\nStacktrace: " + exp.StackTrace, logging);
            }
            finally
            {
                connection.Close();
                GetCustomPhonebook();
            }

            return result;
        }

        private void DeleteCustomPhonebook(string sId)
        {
            int result = 0;
            string sPath = System.AppDomain.CurrentDomain.BaseDirectory;
            sPath = sPath + "Configuration\\config.ini";
            cIniReader _ini = new cIniReader(sPath);
            string mysqlconnection = _ini.ReadString("Database", "ConnectionStringAsterisk", "");
            myLogger.LogInformation("ConnectionString: " + mysqlconnection, logging);
            MySqlConnection connection = new MySqlConnection(mysqlconnection);
            connection.Open();
            
            string sql = "DELETE FROM asterisk.custom_phonebook where id = '"+ sId +"'";
            MySqlCommand insertorupdateCommand = new MySqlCommand(sql, connection);
            insertorupdateCommand = new MySqlCommand(sql, connection);
            try
            {
                result = insertorupdateCommand.ExecuteNonQuery();
            }
            catch (Exception exp)
            {
                myLogger.LogError("DeleteCustomPhonebook: " + exp.Message + "\r\nStacktrace: " + exp.StackTrace, logging);
            }
            finally
            {
                connection.Close();
                GetCustomPhonebook();
            }

        }

        private void GetCustomPhonebook()
        {
            string sPath = System.AppDomain.CurrentDomain.BaseDirectory;
            sPath = sPath + "Configuration\\config.ini";
            cIniReader _ini = new cIniReader(sPath);
            string mysqlconnection = _ini.ReadString("Database", "ConnectionStringAsterisk", "");
            myLogger.LogInformation("ConnectionString: " + mysqlconnection, logging);
            DispatchItIfNeeded(() => { lstCustomPhonebook.Clear(); });
            MySqlConnection connection = new MySqlConnection(mysqlconnection);
            connection.Open();
            //MySqlCommand command = connection.CreateCommand();
            string sql = "SELECT * FROM asterisk.custom_phonebook";
            MySqlCommand readCommand = new MySqlCommand(sql, connection);
            try
            {
                MySqlDataReader rdr = readCommand.ExecuteReader();

                while (rdr.Read())
                {
                    DispatchItIfNeeded(() =>
                    {
                        lstCustomPhonebook.Add(new DataClasses.CustomPhonebook()
                        {
                            Company = rdr["company"].ToString(),
                            CustomerName = rdr["customer_name"].ToString(),
                            Phone1 = rdr["phone1"].ToString(),
                            Phone2 = rdr["phone2"].ToString(),
                            Mobile_Phone = rdr["mobile_phone"].ToString(),
                            ModifiedBy = rdr["modifiedby"].ToString(),
                            Modified = rdr["modified"].ToString()
                        });
                    });
                }
            }
            catch (Exception exp)
            {
                myLogger.LogError("GetUsersDevices: " + exp.Message + "\r\nStacktrace: " + exp.StackTrace, logging);
            }
            finally
            {
                connection.Close();
            }
        }

        private void GetPresencestate()
        {
            string sPath = System.AppDomain.CurrentDomain.BaseDirectory;
            sPath = sPath + "Configuration\\config.ini";
            cIniReader _ini = new cIniReader(sPath);
            mysqlconnection = _ini.ReadString("Database", "ConnectionStringAsterisk", "");
            myLogger.LogInformation("ConnectionString: " + mysqlconnection, logging);


            MySqlConnection connection = new MySqlConnection(mysqlconnection);
            connection.Open();
            MySqlCommand command = connection.CreateCommand();
            string sql = "SELECT * FROM asterisk.presencestate_list";
            MySqlCommand readCommand = new MySqlCommand(sql, connection);
            try
            {
                MySqlDataReader rdr = readCommand.ExecuteReader();

                while (rdr.Read())
                {
                    DispatchItIfNeeded(() =>
                    {
                        lstPresencestate.Add(new DataClasses.Presence()
                        {
                            Presencestate = rdr["type"].ToString(),
                        });
                    });
                }
            }
            catch (Exception exp)
            {
                myLogger.LogError("GetUsersDevices: " + exp.Message + "\r\nStacktrace: " + exp.StackTrace, logging);
            }
            finally
            {
                DispatchItIfNeeded(() =>
                {
                    foreach (var item in lstPresencestate)
                    {
                        comboPresenceState.Items.Add(item.Presencestate);
                    }
                    var aUserState = GetPrecenceState(astUser).Split(',');

                    int iCount = aUserState.Count();

                    if (iCount >= 1)
                    {
                        comboPresenceState.SelectedIndex = comboPresenceState.Items.IndexOf(aUserState[0]);
                    }
                    if (iCount >= 2)
                    {
                        txtSubject.Text = aUserState[1];
                    }
                    if (iCount >= 3)
                    {
                        txtMessage.Text = aUserState[2];
                    }
                });
                GetExtensionStateForAll();
                connection.Close();
            }
        }

        private void GetHistory()
        {
            string sPath = System.AppDomain.CurrentDomain.BaseDirectory;
            sPath = sPath + "Configuration\\config.ini";
            cIniReader _ini = new cIniReader(sPath);
            mysqlconnection = _ini.ReadString("Database", "ConnectionStringCDRDB", "");
            myLogger.LogInformation("ConnectionString: " + mysqlconnection, logging);

            DispatchItIfNeeded(() => lstHistory.Clear());
            //if (bDispatcher == true)
            //{
            //    this.Dispatcher.BeginInvoke(new Action(() => lstHistory.Clear()));
            //}
            MySqlConnection connection = new MySqlConnection(mysqlconnection);
            connection.Open();
            //MySqlCommand command = connection.CreateCommand();


            string sql = "select * from asteriskcdrdb.cdr INNER Join cel on cdr.uniqueid = cel.uniqueid WHERE (cel.eventtype = 'HANGUP') AND cdr.dstchannel like 'SIP/" + astExtension + "%'  ORDER BY cdr.calldate desc";
           // string sql = "SELECT * FROM cdr WHERE dst = '" + astExtension + "' OR src = '" + astExtension + "' OR dstchannel like 'SIP/" + astExtension + "%'  ORDER BY calldate desc";
            MySqlCommand readCommand = new MySqlCommand(sql, connection);
            MySqlDataReader rdr = readCommand.ExecuteReader();

            while (rdr.Read())
            {
                DispatchItIfNeeded(() =>
                {
                    lstHistory.Add(new DataClasses.History()
                    {
                        CallDate = Convert.ToDateTime(rdr["calldate"]),
                        CLid = rdr["clid"].ToString(),
                        Src = rdr["src"].ToString(),
                        Dst = rdr["dst"].ToString(),
                        DContext = rdr["dcontext"].ToString(),
                        UniqueId = rdr["uniqueid"].ToString(),
                        Duration = Convert.ToInt32(rdr["duration"].ToString()),
                        Lastapp = rdr["lastapp"].ToString(),
                        Lastdata = rdr["lastdata"].ToString(),
                        Disposition = rdr["disposition"].ToString(),
                        Did = rdr["did"].ToString(),
                        DstChannel = rdr["dstchannel"].ToString(),
                        Channame = rdr["channame"].ToString(),
                        Cid_num = rdr["cid_num"].ToString(),
                    });
                });
            }
        }

        private void GetUsersDevices()
        {
            string sPath = System.AppDomain.CurrentDomain.BaseDirectory;
            sPath = sPath + "Configuration\\config.ini";
            cIniReader _ini = new cIniReader(sPath);
            mysqlconnection = _ini.ReadString("Database", "ConnectionStringAsterisk", "");
            myLogger.LogInformation("ConnectionString: " + mysqlconnection, logging);

            DispatchItIfNeeded(() => 
            {
                lstLocalExtensions.Clear(); 
            });

            MySqlConnection connection = new MySqlConnection(mysqlconnection);
            connection.Open();
            MySqlCommand command = connection.CreateCommand();
            string sql = "SELECT * FROM asterisk.devices ORDER BY User asc";
            MySqlCommand readCommand = new MySqlCommand(sql, connection);
            try
            {
                MySqlDataReader rdr = readCommand.ExecuteReader();

                while (rdr.Read())
                {
                    if (rdr["user"].ToString() == astExtension)
                    {
                        astCallerId = rdr["description"].ToString();
                        astPeerType = rdr["tech"].ToString().ToUpper(); 
                    }

                    DispatchItIfNeeded(() =>
                    {
                        lstLocalExtensions.Add(new DataClasses.LocalExtension()
                        {
                            Dial = rdr["dial"].ToString(),
                            Extension = rdr["user"].ToString(),
                            Callerid = rdr["description"].ToString(),
                            Tech = rdr["tech"].ToString(),
                            Description = rdr["description"].ToString()
                        });
                    });
                }
            }
            catch (Exception exp)
            {
                myLogger.LogError("GetDevicess: " + exp.Message + "\r\nStacktrace: " + exp.StackTrace, logging);
            }
            finally
            {
                GetExtensionStateForAll();
                connection.Close();
            }
        }

        private void GetRingGroups()
        {
            string sPath = System.AppDomain.CurrentDomain.BaseDirectory;
            sPath = sPath + "Configuration\\config.ini";
            cIniReader _ini = new cIniReader(sPath);
            mysqlconnection = _ini.ReadString("Database", "ConnectionStringAsterisk", "");
            myLogger.LogInformation("ConnectionString: " + mysqlconnection, logging);

            DispatchItIfNeeded(()=>
            {
                lstRingGroups.Clear();
            });

            MySqlConnection connection = new MySqlConnection(mysqlconnection);
            connection.Open();
            MySqlCommand command = connection.CreateCommand();
            string sql = "SELECT * FROM asterisk.ringgroups ORDER BY grpnum desc";
            MySqlCommand readCommand = new MySqlCommand(sql, connection);

            try
            {
                MySqlDataReader rdr = readCommand.ExecuteReader();
                while (rdr.Read())
                {
                    DispatchItIfNeeded(() =>
                    {
                        lstRingGroups.Add(new DataClasses.RingGroups()
                        {
                            Grpum = rdr["grpnum"].ToString(),
                            Grplist = rdr["grplist"].ToString(),
                            Description = rdr["description"].ToString()
                        });

                    });
                }
            }
            catch (Exception exp)
            {
                myLogger.LogError("GetRingGroups: " + exp.Message + "\r\nStacktrace: " + exp.StackTrace, logging);
            }
            finally
            {
                connection.Close();
            }
        }

        private void GetManagerUsers()
        {
            string sPath = System.AppDomain.CurrentDomain.BaseDirectory;
            sPath = sPath + "Configuration\\config.ini";
            cIniReader _ini = new cIniReader(sPath);
            mysqlconnection = _ini.ReadString("Database", "ConnectionStringCDRDB", "");
            myLogger.LogInformation("ConnectionString: " + mysqlconnection, logging);

            //DispatchItIfNeeded(() => lstPresencestate.Clear());

            MySqlConnection connection = new MySqlConnection(mysqlconnection);
            connection.Open();
            MySqlCommand command = connection.CreateCommand();

            string sql = "SELECT * FROM asterisk.manager";
            MySqlCommand readCommand = new MySqlCommand(sql, connection);
            MySqlDataReader rdr = readCommand.ExecuteReader();

            while (rdr.Read())
            {
                DispatchItIfNeeded(() =>
                {
                    lstUserPresencestate.Add(new DataClasses.UserPresence()
                    {
                        User = rdr["name"].ToString()
                    });
                });
            }
            
        }
        #endregion
        //*********************************** DataGrid Actions **************************************************************
        #region DataGridActions

        private void dataGridHistory_LostFocus(object sender, RoutedEventArgs e)
        {
            //SaveDatagridHistory();
        }

        private void dataGridNewState_LostFocus(object sender, RoutedEventArgs e)
        {
           // SaveDatagridNewState();
        }
        #endregion
        //*********************************** DataGrid Events **************************************************************
        #region DataGrid Events
        private void dataGridNewState_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                var addeditems = e.AddedItems;
                activeChannelUp = ((WpfAsteriskCTI.DataClasses.NewState)(((object[])(addeditems))[0])).Channel;
                activeChannelParty = ((WpfAsteriskCTI.DataClasses.NewState)(((object[])(addeditems))[0])).Bridgedchannel;
                if (activeChannelUp != "")
                {
                    ActivateControls();
                }

            }
            catch { };
        }

        private void dataGridNewCallerId_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                var addeditems = e.AddedItems;
                var activeChannelSelectednew = ((WpfAsteriskCTI.DataClasses.NewChannel)(((object[])(addeditems))[0])).Channel;
                activeChannelSelected = activeChannelSelectednew.ToString();
            }
            catch { };
        }

        private void dataGridHistory_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            try
            {
                string toDial = null;
                DataGrid mySelection = sender as DataGrid;
                toDial = ((WpfAsteriskCTI.DataClasses.History)(mySelection.SelectedItem)).Cid_num;
                if (mySelection != null && toDial != null)
                {
                    //var test = mySelection.SelectedItem;
                    //toDial = ((WpfAsteriskCTI.DataClasses.History)(mySelection.SelectedItem)).Cid_num;
                    DialNumber(toDial.ToString());
                }
            }
            catch(Exception exp)
            { 
            
            }
        }

        private void dataGridGlobalPhonebook_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (sender != null)
            {
                DataGrid grid = sender as DataGrid;
                if (grid != null && grid.SelectedItems != null && grid.SelectedItems.Count == 1)
                {
                    DataGridRow dgr = grid.ItemContainerGenerator.ContainerFromItem(grid.SelectedItem) as DataGridRow;
                    string sCustomer = ((WpfAsteriskCTI.DataClasses.CustomPhonebook)(dgr.Item)).CustomerName.ToString();
                    string sCompany = ((WpfAsteriskCTI.DataClasses.CustomPhonebook)(dgr.Item)).Company.ToString();
                    string sPhone1 = ((WpfAsteriskCTI.DataClasses.CustomPhonebook)(dgr.Item)).Phone1.ToString();
                    string sPhone2 = ((WpfAsteriskCTI.DataClasses.CustomPhonebook)(dgr.Item)).Phone2.ToString();
                    string sMobile = ((WpfAsteriskCTI.DataClasses.CustomPhonebook)(dgr.Item)).Mobile_Phone.ToString();
                    dlgAddGlobalPhonebookEntry dlgAdd = new dlgAddGlobalPhonebookEntry(sCustomer, sCompany, sPhone1, sPhone2, sMobile);
                    dlgAdd.Owner = this;
                    dlgAdd.ShowDialog();
                }
            }
        }
        #endregion
        //*********************************** DataGrid Context Menu **************************************************************
        #region ContextMenu
        private void CheckBoxNewState_Unchecked(object sender, RoutedEventArgs e)
        {
            if (label1.Content.ToString() == "Connected")
            {
                NewStatContextMenueSelectionHidden(((System.Windows.Controls.ContentControl)(sender)).Content.ToString());
               // SaveDatagridNewState();
            }
        }
        private void CheckBoxNewState_Checked(object sender, RoutedEventArgs e)
        {
            if (label1.Content.ToString() == "Connected")
            {
                NewStatContextMenueSelectionVisible(((System.Windows.Controls.ContentControl)(sender)).Content.ToString());
               // SaveDatagridNewState();
            }
        }
        private void NewStatContextMenueSelectionVisible(string sHeaderName)
        {
            try
            {
                int index;
                // switch (((System.Windows.Controls.ContentControl)(sender)).Content.ToString())
                switch (sHeaderName)
                {
                    case "CallerId":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "CallerId").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "CallerIdName":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "CallerIdName").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "CallerIdNum":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "CallerIdNum").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "Channel":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "Channel").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "BridgedChannel":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "BridgedChannel").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "ChannelState":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "ChannelState").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "ChannelStateDesc":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "ChannelStateDesc").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "DateReceived":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "DateReceived").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "Privilege":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "Privilege").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "Source":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "Source").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "UniqueId":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "UniqueId").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "BridgedUniqueId":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "BridgedUniqueId").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "PartyCallerIdNum":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "PartyCallerIdNum").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    default:
                        break;
                }
            }
            catch { }
        }
        private void NewStatContextMenueSelectionHidden(string sHeaderName)
        {
            try
            {
                int index;
                // switch (((System.Windows.Controls.ContentControl)(sender)).Content.ToString())
                switch (sHeaderName)
                {
                    case "CallerId":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "CallerId").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "CallerIdName":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "CallerIdName").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "CallerIdNum":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "CallerIdNum").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "Channel":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "Channel").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "BridgedChannel":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "BridgedChannel").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "ChannelState":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "ChannelState").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "ChannelStateDesc":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "ChannelStateDesc").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "DateReceived":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "DateReceived").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "Privilege":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "Privilege").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "Source":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "Source").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "UniqueId":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "UniqueId").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "BridgedUniqueId":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "BridgedUniqueId").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "PartyCallerIdNum":
                        index = dataGridNewState.Columns.IndexOf(dataGridNewState.Columns.Where(x => x.Header.ToString() == "PartyCallerIdNum").FirstOrDefault());
                        dataGridNewState.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    default:
                        break;
                }
            }
            catch { }
        }
        private void CheckBoxHistoryState_Unchecked(object sender, RoutedEventArgs e)
        {
            if (label1.Content.ToString() == "Connected")
            {
                HistoryContextMenueSelectionHidden(((System.Windows.Controls.ContentControl)(sender)).Content.ToString());
            }
        }
        private void CheckBoxHistoryState_Checked(object sender, RoutedEventArgs e)
        {
            if (label1.Content.ToString() == "Connected")
            {
                HistoryContextMenueSelectionVisible(((System.Windows.Controls.ContentControl)(sender)).Content.ToString());
            }
        }
        private void HistoryContextMenueSelectionVisible(string sHeaderName)
        {
            try
            {
                int index;
                // switch (((System.Windows.Controls.ContentControl)(sender)).Content.ToString())
                switch (sHeaderName)
                {
                    case "CallDate":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "CallDate").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "CLid":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "CLid").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "Src":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "Src").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "Dst":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "Dst").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "DContext":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "DContext").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "UniqueId":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "UniqueId").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "Duration":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "Duration").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "Lastapp":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "Lastapp").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "Disposition":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "Disposition").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "Lastdata":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "Lastdata").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "Did":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "Did").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    case "DstChannel":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "DstChannel").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Visible;
                        break;
                    default:
                        break;
                }
            }
            catch { }
        }
        private void HistoryContextMenueSelectionHidden(string sHeaderName)
        {
            try
            {
                int index;
                // switch (((System.Windows.Controls.ContentControl)(sender)).Content.ToString())
                switch (sHeaderName)
                {
                    case "CallDate":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "CallDate").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "CLid":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "CLid").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "Src":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "Src").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "Dst":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "Dst").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "DContext":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "DContext").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "UniqueId":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "UniqueId").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "Duration":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "Duration").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "Lastapp":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "Lastapp").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "Disposition":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "Disposition").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "Lastdata":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "Lastdata").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "Did":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "Did").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    case "DstChannel":
                        index = dataGridHistory.Columns.IndexOf(dataGridHistory.Columns.Where(x => x.Header.ToString() == "DstChannel").FirstOrDefault());
                        dataGridHistory.Columns[index].Visibility = System.Windows.Visibility.Hidden;
                        break;
                    default:
                        break;
                }
            }
            catch { }
        }
        #endregion
        //*********************************** Presence State **************************************************************
        #region precence State
        private void comboPresenceState_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            SetPrecenceState(astUser, comboPresenceState.SelectedValue.ToString() + "," + txtSubject.Text + "," + txtMessage.Text);
        }
        private void txtSubject_LostFocus(object sender, RoutedEventArgs e)
        {
            SetPrecenceState(astUser, comboPresenceState.SelectedValue.ToString() + "," + txtSubject.Text + "," + txtMessage.Text);
        }
        private void txtMessage_LostFocus(object sender, RoutedEventArgs e)
        {
            SetPrecenceState(astUser, comboPresenceState.SelectedValue.ToString() + "," + txtSubject.Text + "," + txtMessage.Text);
        }
        private void txtMessage_TextChanged(object sender, TextChangedEventArgs e)
        {
            SetPrecenceState(astUser, comboPresenceState.SelectedValue.ToString() + "," + txtSubject.Text + "," + txtMessage.Text);
        }
        #endregion
    }
}